/* GB2312 Encoding */
/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : Stepper.h
  - Author        : liuzhihua (liuzhihuawy@163.com)
  - Update date   : 2023.04.24
  -	Brief         : Stepper Motor Driver
  - Version       : v1.0
-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
|                               UPDATE NOTE                             |
-----------------------------------------------------------------------*/
/**
  * Update note:
  * ------------   ---------------   ----------------------------------
  *     Date            Author                       Note
  * ------------   ---------------   ----------------------------------
  *  2023.04.22       liuzhihua                   Create file          
***/

#ifndef _STEPPER_HPP_
#define _STEPPER_HPP_
/*-----------------------------------------------------------------------
|                               INCLUDES                                |
-----------------------------------------------------------------------*/
#include <string.h>
#include <stdint.h>
#include "dma.h"
#include "tim.h"
#include "gpio.h"
#include "Stepper_driver.h"
/*-----------------------------------------------------------------------
|                                DEFINES                                |
-----------------------------------------------------------------------*/
class Stepper;

class limitSW
{
    public:
        GPIO_TypeDef *gpio;
        uint16_t pinBit;
        uint8_t defaultVoltage;
        limitSW(void)
        {
            this->attachPin(NULL, 0, 0);
        }
        limitSW(GPIO_TypeDef *gpio, uint16_t pinBit, uint8_t defaultVoltage)
        {
            this->attachPin(gpio, pinBit, defaultVoltage);
        }

        void attachPin(GPIO_TypeDef *gpio, uint16_t pinBit, uint8_t defaultVoltage)
        {
            this->gpio = gpio;
            this->pinBit = pinBit;
            this->defaultVoltage = defaultVoltage;
        }

        uint8_t getState(void)
        {
            return (HAL_GPIO_ReadPin(this->gpio, this->pinBit)
                                         == (GPIO_PinState)this->defaultVoltage ? 0 : 1);
        }

};

class Stepper
{
    private:
        
    public:
        Stepper(uint32_t oneCirclePulseNum, long minStep, long maxStep);
        stepperDriver_t driver;
        limitSW limitsw1; /* dir < 0 */
        limitSW limitsw2; /* dir > 0 */
        uint32_t oneCirclePulseNum;
        long limitMinStep;
        long limitMaxStep;
        bool limitStepState;

        void attachDirPin(GPIO_TypeDef *gpio,
                          uint16_t pinBit,
                          uint16_t defaultVoltage);

        void attachEnPin(GPIO_TypeDef *gpio,
                         uint16_t pinBit,
                         uint16_t defaultVoltage);

        void attachPulsePin(GPIO_TypeDef *gpio,
                            uint16_t pinBit,
                            TIM_HandleTypeDef *htim,
                            uint8_t channel);

        void attachLimitSW1(GPIO_TypeDef *gpio,
                            uint16_t pinBit,
                            uint16_t defaultVoltage);
        void attachLimitSW2(GPIO_TypeDef *gpio,
                            uint16_t pinBit,
                            uint16_t defaultVoltage);
        void extiCallback(uint16_t GPIO_Pin);

        void setDriverEnableStatus(uint32_t status);
        uint32_t getDriverEnableStatus(void);
        void setSpeed(double speed);
        double getSpeed(void);
        long long getStep(void);
        double getAngle(void);
        StepperDriverState_t getMoveState(void);
        //motion
        void moveStep(long step);
        void moveToStep(long long stepPos);
        void rotateAngle(float targetAngle);
        void rotateToAngle(float targetAngle);
        void stop(void);

        void limitStepEnable(void);
        void limitStepDisable(void);
        StepperDriverState_t reset(int dir);
        long angleToStep(double angle);
        double stepToAngle(long long step);
        
};



/*-----------------------------------------------------------------------
|                                  API                                  |
-----------------------------------------------------------------------*/






#endif
